/**
 * Ts高级类型
 */
interface User {
  name: string
  sex: string
  age: number
}

interface DeadPerson {
  name: string
}
type typeFun = () => string

class User2 {
  name: string
  sex: string
  age: number
  constructor(name: string, sex: string, age: number) {
    this.name = name
    this.sex = sex
    this.age = age
  }
}
// 全部只读(常用与只读)
let a: Readonly<User> = { name: '11', sex: 'm', age: 5 }
// 全部可选(常用与需要全部非必选)
let b: Partial<User> = { name: '11', sex: 'm', age: 5 }
// 选择某些属性(常用与需要选择某些属性时)
let c: Pick<User, 'name'> = { name: '11' }
// 将某个对象的所有属性值的类型全部转为某个类型(常用于需要全部更改类型时)
let d: Record<keyof User, number>
// 排除DeadPerson中的User(常用于只需要具体的几个属性值时)
let e: Exclude<DeadPerson, User> = { name: 'm' }
// 提取DeadPerson中的User(常用于只需要具体的几个属性值时)
let g: Extract<User, DeadPerson> = { name: 'sdfdf', sex: 'sdfd', age: 500 }
// 获取函数的返回值类型(常用与不知道某个函数的返回值属性时)
let f: ReturnType<typeFun> = '55'
// 获取某个实例的类型(常用于不知道某个对象的具体属性时)
let h: InstanceType<typeof User2> = { name: 'sdfd', age: 5, sex: 'sdfd' }

/*type Readonly<T> = {
  readonly [P in keyof T]: T[P]
}
type Partial<T> = {
  [P in keyof T]?: T[P]
}
type Pick<T, K extends keyof T> = {
  [P in K]: T[P]
}
type Record<K extends string, T> = {
  [P in K]: T
}
type Nullable<T> = { [P in keyof T]: T[P] | null }
type Partial<T> = { [P in keyof T]?: T[P] }*/
// Exclude<T, U> -- 从T中剔除可以赋值给U的类型。
// Extract<T, U> -- 提取T中可以赋值给U的类型。
// NonNullable<T> -- 从T中剔除null和undefined。
// ReturnType<T> -- 获取函数返回值类型。
// InstanceType<T> -- 获取构造函数类型的实例类型。
/*type T00 = Exclude<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // "b" | "d"
type T01 = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'> // "a" | "c"

type T02 = Exclude<string | number | (() => void), Function> // string | number
type T03 = Extract<string | number | (() => void), Function> // () => void

type T04 = NonNullable<string | number | undefined> // string | number
type T05 = NonNullable<(() => string) | string[] | null | undefined> // (() => string) | string[]

function f1(s: string) {
  return { a: 1, b: s }
}

class C {
  x = 0
  y = 0
}

type T10 = ReturnType<() => string> // string
type T11 = ReturnType<(s: string) => void> // void
type T12 = ReturnType<<T>() => T> // {}
type T13 = ReturnType<<T extends U, U extends number[]>() => T> // number[]
type T14 = ReturnType<typeof f1> // { a: number, b: string }
type T15 = ReturnType<any> // any
type T16 = ReturnType<never> // any
type T17 = ReturnType<string> // Error
type T18 = ReturnType<Function> // Error

type T20 = InstanceType<typeof C> // C
type T21 = InstanceType<any> // any
type T22 = InstanceType<never> // any
type T23 = InstanceType<string> // Error
type T24 = InstanceType<Function> // Error*/
export default User
